iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
自我挑戰組

SPYxFRONTEND ~ 懂一點後端真是讓人哇哭哇哭系列 第 7

[Day7] 來到 call API 的第一道門 ~ AJAX - XMLHttpRequest 篇

  • 分享至 

  • xImage
  •  

前言

資料取得的三種方法,

1.變數 → 2.import檔案 → 3. call API

今天終於來到 3. call API 了~~~

本日正文

其實如果是 call API 拿資料的話,
有很多種方式,
首先就先來了解一下 AJAX 是什麼吧!

AJAX

AJAX 是由 Asynchronous JavaScript and XML 縮寫而來,
由字面上來就是指發送非同步請求向遠端伺服器(API)交換資料,
早期 XML 比較夯,所以交換資料用的格式是 XML 居多,
而現在比較流行的應該是 JSON 格式,
如果是現在的話才出現這個概念,
AJAX 可能要取名叫 AJAJ 了XD (這要怎麼唸啊XD)

W3Schools 上是這樣介紹 AJAX 的:

AJAX is a developer's dream, because you can:

Update a web page without reloading the page
Request data from a server - after the page has loaded
Receive data from a server - after the page has loaded
Send data to a server - in the background

AJAX 是開發者的夢想,因為你可以不需要重新載入頁面就自動更新
沒錯,這跟本系列文的標題是呼應的!

你再也不用高級手工藝只是寫死資料,
你可以用 AJAX 來即時拿到資料,
甚至還可以發更改資料的要求,
讓資料產生異動。

XMLHttpRequest (XHR)

因此 AJAX 並不是指特定的單一工具,
而是一種概念,有很多實作 AJAX 的工具,
例如最原始的 XMLHttpRequest (簡稱 XHR),再來還有 fetch,
以及這個系列文一開始有提到的 axios,
那麼今天從 XHR 開始吧!

(PS. 為了避免一直去 call API,
今天的範例寫成點擊按鈕才會去 call)

首先要先宣告 XHR 物件:

const xhr = new XMLHttpRequest();

再來就要正式去拿資料了,

xhr.open("get", sourceUrl, true);
xhr.send(null);

open 意思是要開一個 request,
open 括號裡面帶的第一個參數 get 是代表你要開怎樣的請求

get =>是指要向對方(伺服器)拿資料
post =>要傳資料給對方(伺服器)

那要拿資料當然要填入網址,sourceUrl 今天是用政府資料開放平臺提供的API:
(PS. 平臺裡面都是開放資料,任人自由取用,歡迎大家多逛逛哦)

const sourceUrl =
    "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=rdec-key-123-45678-011121314";

我在正式寫之前通常會習慣到瀏覽器開啟該網址直接看資料回傳的樣子,
或甚至是把它儲存下來成 json 檔再 import,
等到你程式寫好再把 import 的檔案換成去 call API 就好。
(因為這樣可以避免一直無效的去 call API,
就是你寫程式還在測試,但因為你後面資料處理邏輯沒寫好之類,
你卻一直執行程式,導致一直 call API)

像這樣:
https://ithelp.ithome.com.tw/upload/images/20220908/20129873uBTCnrkxEs.png

再來就是用 xhr.send 傳送該請求給對方(伺服器)。

但是如果這時候你用 console.log(xhr.responseText) 來看看 xhr 的回傳結果,
是沒有東西的:
https://ithelp.ithome.com.tw/upload/images/20220908/20129873d1FYk0k3v6.png

原因是出在 xhr.open 所帶的第三個參數:true
這個是指要不要用非同步模式:

true :非同步 - 不會等資料回傳就繼續往下執行
false :同步 - 等資料回傳才繼續往下執行

因此我們要多寫一個等到拿到資料要怎麼處理,
也就是 xhr.onload,這意思就是等到 XHR 回傳後要執行的動作

xhr.onload = function () {
	console.log(xhr.responseText);
};

這時候你就會看到有資料回傳了~

然後原諒我快天窗orz 所以我先很快帶一下我後來做的加工:

function App() {
  const sourceUrl =
    "https://opendata.cwb.gov.tw/api/v1/rest/datastore/F-C0032-001?Authorization=rdec-key-123-45678-011121314";
  const [dataResult, setdataResult] = useState([]);

function fetchData(){
  const xhr = new XMLHttpRequest();
  xhr.open("get", sourceUrl, true);
  xhr.send(null);
  console.log(xhr.responseText);
  xhr.onload = function () {
    setdataResult(JSON.parse(xhr.responseText));
  };
}

  return (
    <ChakraProvider theme={theme}>
      <>
        <Text my={4} fontSize="p" textAlign="center">
          sourceUrl: {sourceUrl}
        </Text>
        <Text my={4} as="h2" fontSize="2xl" textAlign="center">
          總共 {dataResult.length === 0 ? 0 : dataResult.records?.location?.length } 筆資料
        </Text>
        <Center>
          <Button onClick={fetchData}>取得資料</Button>
        </Center>
      </>
    </ChakraProvider>
  );
}

這邊我就是在畫面上寫了一個按鈕取得資料,點擊後會去執行 fetchData
fetchData 裡面會發 XHR 拿到資料,
另外我也將資料拿到的結果儲存起來:setdataResult(JSON.parse(xhr.responseText))
渲染到畫面上,
因此原本是顯示 0 筆資料,
在我點擊取得資料 後會顯示取得 22 筆資料,
操作如下:
XHR

然後接下來幾天都會在 AJAX 當中,
原諒我今天比較趕,
明天開始再好好說明一下orz

參考資料

什麼是 Ajax? 搞懂非同步請求 (Async request) 概念
AJAX Introduction - W3Schools

後記

其實真的為了寫這篇文章去看了一些資料,才真的搞懂 AJAX、XHR、fetch、axios 的不同,
不然之前只是懵懵懂懂覺得這些都是可以去 call API 拿資料的一個手法而已orz
希望接下來我可以藉由這個機會把這些弄清楚~~~


上一篇
[Day6] 巧婦難為無米之炊~ 第一步就先從取得資料開始吧!之 import 篇
下一篇
[Day8] 用 fetch 拿資料好愜意
系列文
SPYxFRONTEND ~ 懂一點後端真是讓人哇哭哇哭30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言